
#ifndef _UTIL_HTTP_SERVER_H_
#define _UTIL_HTTP_SERVER_H_

#include "xtypes.h"


char* ScanForChar(char* startPos, size_t length, char charToFind);

//Http

#define HTTPCODE_OK						200
#define HTTPCODE_CREATED				201
#define HTTPCODE_ACCEPTED				202
#define HTTPCODE_NO_CONTENT				204
#define HTTPCODE_MOVED_PERMANENTLY		301
#define HTTPCODE_MOVED_TEMPORARILY		302
#define HTTPCODE_NOT_MODIFIED			304
#define HTTPCODE_BAD_REQUEST			400
#define HTTPCODE_UNAUTHORIZED			401
#define HTTPCODE_FORBIDDEN				403
#define HTTPCODE_NOT_FOUND				404
#define HTTPCODE_INTERNAL_SERVER_ERROR	500
#define HTTPCODE_NOT_IMPLEMENTED		501
#define HTTPCODE_BAD_GATEWAY			502
#define HTTPCODE_SERVICE_UNAVAILABLE	503

struct HttpStatus
{
	int			code;
	char*		codeText;
	char*		description;
};

HttpStatus* FindHttpStatus(int code);

#define VERB_UNKNOWN	0
#define VERB_GET		1

#define HTTP_10			0x10
#define HTTP_11			0x11

#define MAX_URI_PATH	256
#define MAX_URI_QUERY	256

struct Uri
{
	char path[MAX_URI_PATH];
	char query[MAX_URI_QUERY];
};

#define MAX_HEADER_NAME_LENGTH		128
#define MAX_HEADER_VALUE_LENGTH		512

struct Header
{
	char name[MAX_HEADER_NAME_LENGTH+1];
	char value[MAX_HEADER_VALUE_LENGTH+1];

	struct Header* next;
};

struct HeaderCollection
{
	size_t	count;
	Header*	head;
};

BOOL AddHeaderToCollection(HeaderCollection* collection, Header* header);
Header* FindHeaderInCollection(HeaderCollection* collection, char* name);
BOOL RemoveHeaderFromCollection(HeaderCollection* collection, char* name);

HeaderCollection* CreateHeaderCollection();
void DestroyHeaderCollection(HeaderCollection* collection);
void CleanupHeaderCollection(HeaderCollection* collection);

BOOL ValidateHeader(char* name, char* value);
Header* CreateHeader(char* name, char* value);
void DestroyHeader(Header* header);





//Request

struct Request
{
	int					verb;
	Uri					uri;
	int					version;
	HeaderCollection	headers;
};

xResult CheckForEndOfRequest(char* buffer, size_t lengthRemaining, BOOL *endOfRequest);
xResult CountHeaders(char* startPos, size_t length, size_t* headerCount);

Request* CreateRequest();
void DestroyRequest(Request* request);
void CleanupRequest(Request* request);
xResult ParseUri(char* string, Uri* uri);
xResult ParseHeader(char* string, Header* header);
xResult ParseRequest(BYTE* buffer, size_t bufferLength, Request* request);
BOOL IsKeepAlive(Request* request);
size_t GetContentLength(Request* request);






//Response

struct Response
{
	int					version;
	int					code;
	HeaderCollection	headers;
};

Response* CreateResponse();
void DestroyResponse(Response* response);
void CleanupResponse(Response* response);

BOOL SetContentLength(Response* response, size_t length);
BOOL SetServer(Response* response, char* server);
BOOL SetContentType(Response* response, char* type);
BOOL SetConnection(Response* response, char* type);












#endif //_UTIL_HTTP_SERVER_H_



